using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;

namespace SeataNet.Core.TCC
{
    /// <summary>
    /// TCC服务注册接口
    /// </summary>
    public interface ITccServiceRegistry
    {
        /// <summary>
        /// 注册TCC服务
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        /// <param name="serviceInstance">服务实例</param>
        void RegisterService(Type serviceType, object serviceInstance);

        /// <summary>
        /// 注册TCC服务
        /// </summary>
        /// <typeparam name="TService">服务类型</typeparam>
        /// <param name="serviceInstance">服务实例</param>
        void RegisterService<TService>(TService serviceInstance) where TService : class;

        /// <summary>
        /// 获取TCC服务
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        /// <returns>服务实例</returns>
        object? GetService(Type serviceType);

        /// <summary>
        /// 获取TCC服务
        /// </summary>
        /// <typeparam name="TService">服务类型</typeparam>
        /// <returns>服务实例</returns>
        TService? GetService<TService>() where TService : class;

        /// <summary>
        /// 检查服务是否已注册
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        /// <returns>是否已注册</returns>
        bool IsRegistered(Type serviceType);

        /// <summary>
        /// 检查服务是否已注册
        /// </summary>
        /// <typeparam name="TService">服务类型</typeparam>
        /// <returns>是否已注册</returns>
        bool IsRegistered<TService>() where TService : class;

        /// <summary>
        /// 注销TCC服务
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        void UnregisterService(Type serviceType);

        /// <summary>
        /// 注销TCC服务
        /// </summary>
        /// <typeparam name="TService">服务类型</typeparam>
        void UnregisterService<TService>() where TService : class;

        /// <summary>
        /// 获取所有已注册的服务类型
        /// </summary>
        /// <returns>服务类型列表</returns>
        IEnumerable<Type> GetRegisteredServiceTypes();
    }

    /// <summary>
    /// 默认TCC服务注册实现
    /// </summary>
    public class DefaultTccServiceRegistry : ITccServiceRegistry
    {
        private readonly ILogger<DefaultTccServiceRegistry> _logger;
        private readonly ConcurrentDictionary<Type, object> _services;

        public DefaultTccServiceRegistry(ILogger<DefaultTccServiceRegistry> logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _services = new ConcurrentDictionary<Type, object>();
        }

        /// <summary>
        /// 注册TCC服务
        /// </summary>
        public void RegisterService(Type serviceType, object serviceInstance)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            if (serviceInstance == null)
            {
                throw new ArgumentNullException(nameof(serviceInstance));
            }

            _services.AddOrUpdate(serviceType, serviceInstance, (key, oldValue) => serviceInstance);

            _logger.LogInformation("Registered TCC service: {ServiceType}", serviceType.FullName);
        }

        /// <summary>
        /// 注册TCC服务
        /// </summary>
        public void RegisterService<TService>(TService serviceInstance) where TService : class
        {
            if (serviceInstance == null)
            {
                throw new ArgumentNullException(nameof(serviceInstance));
            }

            RegisterService(typeof(TService), serviceInstance);
        }

        /// <summary>
        /// 获取TCC服务
        /// </summary>
        public object? GetService(Type serviceType)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            _services.TryGetValue(serviceType, out var serviceInstance);
            return serviceInstance;
        }

        /// <summary>
        /// 获取TCC服务
        /// </summary>
        public TService? GetService<TService>() where TService : class
        {
            return GetService(typeof(TService)) as TService;
        }

        /// <summary>
        /// 检查服务是否已注册
        /// </summary>
        public bool IsRegistered(Type serviceType)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            return _services.ContainsKey(serviceType);
        }

        /// <summary>
        /// 检查服务是否已注册
        /// </summary>
        public bool IsRegistered<TService>() where TService : class
        {
            return IsRegistered(typeof(TService));
        }

        /// <summary>
        /// 注销TCC服务
        /// </summary>
        public void UnregisterService(Type serviceType)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            if (_services.TryRemove(serviceType, out _))
            {
                _logger.LogInformation("Unregistered TCC service: {ServiceType}", serviceType.FullName);
            }
        }

        /// <summary>
        /// 注销TCC服务
        /// </summary>
        public void UnregisterService<TService>() where TService : class
        {
            UnregisterService(typeof(TService));
        }

        /// <summary>
        /// 获取所有已注册的服务类型
        /// </summary>
        public IEnumerable<Type> GetRegisteredServiceTypes()
        {
            return _services.Keys.ToList();
        }
    }
}
